package cn.smartopen.aispace.controller.merchant;

import java.security.SignatureException;
import java.util.ArrayList;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.smartopen.aispace.config.Config;
import cn.smartopen.aispace.entity.AppidEntity;
import cn.smartopen.aispace.entity.ServiceUser;
import cn.smartopen.aispace.service.merchant.APPIDService;
import cn.smartopen.aispace.status.ResponseCode;
import cn.smartopen.aispace.status.ResponseResult;
import cn.smartopen.aispace.utils.SignatureVerifier;
import cn.smartopen.aispace.utils.Utils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;

@Tag(name = "APPID", description = "服务商申请APPID和登录接口")
@Slf4j
@RestController
public class APPIDController {

    @Autowired
    APPIDService appidService;

    @Operation(summary = "获取随机字符串", description = "用户获取随机字符串用于签名使用")
    @GetMapping("/appid/randomstr")
    public ResponseResult<String> getRandomStr(HttpSession session) {
        String randomStr = Utils.generateRandomString(Config.RANDOM_STR_LENGTH);
        session.setAttribute("randomStr", randomStr);
        return new ResponseResult<>(ResponseCode.SUCCESS, randomStr);
    }

    @Operation(summary = "是否登录", description = "判断用户是否已经登录")
    @GetMapping("/appid/login")
    public ResponseResult<String> loginStatus(HttpSession session) {
        var loginStatus = session.getAttribute("loginStatus");
        var status = loginStatus == null ? false : loginStatus;
        if ((boolean) status) {
            return new ResponseResult<>(ResponseCode.SUCCESS);
        } else {
            return new ResponseResult<>(ResponseCode.NO_LOGIN);
        }
    }

    @Operation(summary = "登录", description = "用户登录提交签名信息进行登录")
    @PostMapping("/appid/login")
    public ResponseResult<String> registAPPID(
            HttpSession session,
            @Parameter(description = "用户公钥") @RequestParam("publicKey") String publicKey,
            @Parameter(description = "用户签名信息") @RequestParam("signatureMessage") String signatureMessage) {
        String originStr = (String) session.getAttribute("randomStr");

        boolean res = false;

        try {
            res = SignatureVerifier.validate(signatureMessage, originStr, publicKey);
        } catch (SignatureException e) {
            log.error(e.getMessage());
        }

        if (res) {
            session.setAttribute("loginStatus", true);
            session.setAttribute("publicKey", publicKey);
            return new ResponseResult<>(ResponseCode.SUCCESS);
        } else {
            return new ResponseResult<>(ResponseCode.SIGNATURE_ERROR);
        }

    }

    @Operation(summary = "退出", description = "用户退出登录")
    @GetMapping("/appid/quit")
    public ResponseResult<String> quitSystem(
            HttpSession session) {

        session.removeAttribute("tandomStr");
        session.removeAttribute("loginStatus");
        session.removeAttribute("publicKey");

        return new ResponseResult<>(ResponseCode.SUCCESS);
    }

    @Operation(summary =  "登录用户信息", description = "用户登录后获取用户登录信息")
    @GetMapping("/appid/userinfo")
    public ResponseResult<ServiceUser> userInfo(HttpSession session){
        String publicKey = (String) session.getAttribute("publicKey");

        var serviceUser = appidService.getServiceUserByPublicKey(publicKey);

        return new ResponseResult<ServiceUser>(ResponseCode.SUCCESS,serviceUser);
    }


    /**
     * 用户申请APPID要保证域名的@@@唯一性@@@
     * @param session
     * @param domainName
     * @param signatureMessage
     * @return
     */

    @Operation(summary =  "申请APPID", description = "服务商申请APPID")
    @PostMapping("/appid/apply")
    public ResponseResult<String> applyAppid(HttpSession session,
        @Parameter(description = "平台域名") @RequestParam("domainName") String domainName,
        @Parameter(description = "域名签名") @RequestParam("signatureMessage") String signatureMessage
    ){
        String publicKey = (String) session.getAttribute("publicKey");
        // 验证签名
        boolean res = false;

        try {
            res = SignatureVerifier.validate(signatureMessage, domainName, publicKey);
        } catch (SignatureException e) {
            log.error(e.getMessage());
        }

        if (!res) {
            return new ResponseResult<>(ResponseCode.SIGNATURE_ERROR);
        }

        // 生成APPID
        String appId = Utils.generateSignature(domainName, signatureMessage);
        // 查询用户主键
        String serviceUserPkId = appidService.getServiceUserPkIdByPublicKey(publicKey);
        // 处理APPID的创建
        var appidEntity = new AppidEntity(appId, domainName,Long.parseLong(serviceUserPkId));
        var msg = appidService.createAppId(appidEntity,Long.parseLong(serviceUserPkId));

        if(msg=="SUCCESS"){
            msg = appidEntity.getPkId().toString();
        }
        return new ResponseResult<String>(ResponseCode.SUCCESS,msg);
    }

    @Operation(summary =  "获取注册APPID", description = "用户获取自己注册的APPID")
    @GetMapping("/appid/list")
    public ResponseResult<ArrayList<AppidEntity>> appIdList(HttpSession session){
        String publicKey = (String) session.getAttribute("publicKey");

        var appidList = appidService.getAppIdListByPublicKey(publicKey);

        return new ResponseResult<ArrayList<AppidEntity>>(ResponseCode.SUCCESS,appidList);
    }

    @Operation(summary =  "删除APPID", description = "用户删除自己注册的APPID")
    @DeleteMapping("/appid/delete/{pkId}")
    public ResponseResult<String> deleteAppId(HttpSession session,
        @PathVariable("pkId") Long pkId
    ){
        String publicKey = (String) session.getAttribute("publicKey");

        appidService.deleteAppIdByPkIdAndPublicKey(pkId,publicKey);

        return new ResponseResult<String>(ResponseCode.SUCCESS);
    }

    


}
